home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 December / PCWorld_2007-12_cd.bin / domacnost a kancelar / autoit / autoit-v3-setup.exe / Examples / GUI / Advanced / DllCallBack.au3 < prev    next >
Encoding:
Text File  |  2007-09-08  |  8.4 KB  |  200 lines

  1. Global Const $gi_DllCallBack_uiMsg = 0x7FFF ; WM_USER + 0x7BFF
  2. Global Const $gi_DllCallBack_MaxStubs = 64
  3.  
  4. Global $gp_DllCallBack_SendMessage = 0
  5. Global $gh_DllCallBack_hUser32 = 0
  6. Global $gi_DllCallBack_StubCount = 0
  7. Global $gh_DllCallBack_hWnd = GUICreate("au3_Callback")
  8. Global $ga_DllCallBack_sParameters[$gi_DllCallBack_MaxStubs + 1]
  9. Global $ga_DllCallBack_nParameters[$gi_DllCallBack_MaxStubs + 1]
  10. Global $ga_DllCallBack_sFunctions[$gi_DllCallBack_MaxStubs + 1]
  11. Global $ga_DllCallBack_hGlobals[$gi_DllCallBack_MaxStubs + 1]
  12.  
  13. ;===============================================================================
  14. ;
  15. ; Function Name:       _DllCallBack
  16. ; Description:        Allocates executeable memory and creates a procedure
  17. ;                    which forwards a pointer to its arguments to a Window
  18. ; Parameter(s):        $sFunction - Name of handler function
  19. ;                    $sParameters - DllStruct like parameter definition
  20. ;                    $fCedecl, Optional - use cdecl calling convention (default is stdcall)
  21. ; Requirement(s):
  22. ; Return Value(s):    Pointer to created stub or NULL on error
  23. ; @error Value(s):    1 = Error allocating memory
  24. ;                    2 = Error Loading User32.dll
  25. ;                    3 = Failed to get the address of SendMessage
  26. ;                    4 = Too many callbacks
  27. ;                    5 = GUIRegisterMsg() Failed
  28. ;                    6 = $sParameters Fromat wrong
  29. ;
  30. ; Author(s):         Florian Fida
  31. ; Notes:            The number of coexistent callback stubs is limited to 64.
  32. ;                    Windows message WM_USER + 0x7BFF is used by this function.
  33. ;
  34. ;===============================================================================
  35. ;
  36. Func _DllCallBack($sFunction, $sParameters = "", $fcdecl = False)
  37.     Local $hGlobal, $hUser32, $pSendMessage_RelAddr, $vStub, $i, $nParameters, $vParameters, $wParam = -1, $nParameters_struct = -1
  38.     If $sParameters = "" Or $sParameters = Default Then
  39.        $nParameters = 0
  40.     Else
  41.        $vParameters = DllStructCreate($sParameters)
  42.        If @error Then Return SetError(6,0,0)
  43.        $nParameters = DllStructGetSize($vParameters) / 4
  44.        If $nParameters <> Int($nParameters) Or @error Then Return SetError(6, 0, 0)
  45.        For $i = 1 To 256
  46.           DllStructGetData($vParameters,$i)
  47.           If @error Then 
  48.              $nParameters_struct = $i - 1
  49.              ExitLoop
  50.           EndIf
  51.        Next
  52.        If $nParameters_struct < 0 Then SetError(6, 0, 0)
  53.     EndIf
  54.     For $i = 0 To $gi_DllCallBack_MaxStubs
  55.         If Not $ga_DllCallBack_hGlobals[$i] Then
  56.             $wParam = $i
  57.             ExitLoop
  58.         EndIf
  59.     Next
  60.     If $wParam = -1 Then Return SetError(4, 0, 0)
  61.     If Not GUIRegisterMsg($gi_DllCallBack_uiMsg, "__DllCallBack_MsgHandler") Then Return SetError(5, 0, 0)
  62.     $hGlobal = DllCall("kernel32.dll", "ptr", "GlobalAlloc", "uint", 0, "dword", 87) ; 87 = Size of stub
  63.     If @error Then Return SetError(1, 0, 0)
  64.     If $hGlobal[0] = 0 Then Return SetError(1, 0, 0)
  65.     $hGlobal = $hGlobal[0]
  66.     If $gp_DllCallBack_SendMessage = 0 Then
  67.         $hUser32 = DllCall("kernel32.dll", "ptr", "LoadLibrary", "str", "user32.dll")
  68.         If @error Then Return SetError(2, 0, 0)
  69.         If $hUser32[0] = 0 Then SetError(2, 0, 0)
  70.         $gh_DllCallBack_hUser32 = $hUser32[0]
  71.         $pSendMessage = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", $gh_DllCallBack_hUser32, "str", "SendMessageA")
  72.         If @error Then Return SetError(3, 0, 0)
  73.         If $pSendMessage = 0 Then Return SetError(3, 0, 0)
  74.         $gp_DllCallBack_SendMessage = $pSendMessage[0]
  75.     EndIf
  76.     $pSendMessage_RelAddr = $gp_DllCallBack_SendMessage - ($hGlobal + 0x22)
  77.     $vStub = DllStructCreate("ubyte[30];" _ ; 1 Stub Part 1
  78.              & "ptr;" _ ; 2 Address of SendMessage relative to $+22 (pTo - $+22)
  79.              & "ubyte[9];" _ ; 3 Stub Part 2
  80.              & "byte[6];" _ ; 4 6 bytes nothing
  81.              & "long;" _ ; 5 nParams
  82.              & "hwnd;" _ ; 6 hwnd
  83.              & "uint;" _ ; 7 msg
  84.              & "uint;", $hGlobal) ; 8 wparam
  85.     #cs Stub Part 1
  86.       $-1      > CC               INT3                                       ; Breakpoint (Optional)
  87.       $ ==>    > E8 00000000      CALL 0015F056                            ; CALL next instruction
  88.       $+5      > 58               POP EAX                                  ; Get return address from last CALL
  89.       $+6      > 8D90 2B000000    LEA EDX,DWORD PTR DS:[EAX+2B]            ; Load address for parameters
  90.       $+C      > 8D4424 04        LEA EAX,DWORD PTR SS:[ESP+4]             ; Load stack pointer
  91.       $+10     > FF32             PUSH DWORD PTR DS:[EDX]                  ; Push nr. of parameters (for later ESP correction)
  92.       $+12     > 50               PUSH EAX                                 ; Push lParam - Stack pointer
  93.       $+13     > FF72 0C          PUSH DWORD PTR DS:[EDX+C]                ; Push wParam
  94.       $+16     > FF72 08          PUSH DWORD PTR DS:[EDX+8]                ; Push Msg
  95.       $+19     > FF72 04          PUSH DWORD PTR DS:[EDX+4]                ; Push hWnd
  96.       $+1C     > E8 39F2BB77      CALL USER32.77D1E2AB                     ; Call SendMessageA
  97.     #ce
  98.     DllStructSetData($vStub, 1, Binary("0x90E800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8"))
  99.     DllStructSetData($vStub, 2, $pSendMessage_RelAddr)
  100.     If $fcdecl <> False Then
  101.         #cs Stub Part 2 - cdecl
  102.             $+21     > 90               NOP
  103.             $+22     > 5A               POP EDX
  104.             $+23     > 59               POP ECX
  105.             $+24     > 90               NOP
  106.             $+25     > 90               NOP
  107.             $+26     > 90               NOP
  108.             $+27     > FFE1             JMP ECX
  109.             $+29     > 90               NOP
  110.         #ce
  111.         DllStructSetData($vStub, 3, Binary("0x905A59909090FFE190"))
  112.     Else
  113.         #cs Stub Part 2 - stdcall
  114.             $+21     > 90               NOP
  115.             $+22     > 5A               POP EDX
  116.             $+23     > 59               POP ECX
  117.             $+24     > 8D2494           LEA ESP,DWORD PTR SS:[ESP+EDX*4]
  118.             $+27     > FFE1             JMP ECX
  119.             $+29     > 90               NOP
  120.         #ce
  121.         DllStructSetData($vStub, 3, Binary("0x905A598D2494FFE190"))
  122.     EndIf
  123. ;~    $+2A     > 000000000000
  124.     DllStructSetData($vStub, 4, Binary("0x000000000000"))
  125. ;~    $+30     > 00000000
  126.     DllStructSetData($vStub, 5, $nParameters)
  127. ;~    $+34     > 00000000
  128.     DllStructSetData($vStub, 6, $gh_DllCallBack_hWnd)
  129. ;~    $+38     > 00000000
  130.     DllStructSetData($vStub, 7, $gi_DllCallBack_uiMsg)
  131. ;~    $+3C     > 00000000
  132.     DllStructSetData($vStub, 8, $wParam)
  133.     $gi_DllCallBack_StubCount += 1
  134.     $ga_DllCallBack_hGlobals[$wParam] = $hGlobal
  135.     $ga_DllCallBack_sFunctions[$wParam] = $sFunction
  136.     $ga_DllCallBack_sParameters[$wParam] = $sParameters
  137.     $ga_DllCallBack_nParameters[$wParam] = $nParameters_struct
  138.     Return $hGlobal
  139. EndFunc   ;==>_DllCallBack
  140.  
  141.  
  142. ;===============================================================================
  143. ;
  144. ; Function Name:    _DllCallBack_Free
  145. ; Description:        Frees memory from global heap allocated by _DllCallBackAlloc
  146. ; Parameter(s):        $hStub - Pointer to stub
  147. ; Requirement(s):
  148. ; Return Value(s):    On Success: True
  149. ;                    On Failure: False
  150. ; @error Value(s):    1 - Error freeing memory
  151. ;                    2 - Error freeing User32.dll
  152. ; Author(s):        Florian Fida
  153. ;
  154. ;===============================================================================
  155. ;
  156. Func _DllCallBack_Free(ByRef $hStub)
  157.     Local $aTmp, $i
  158.     If $hStub > 0 Then
  159.         $aTmp = DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $hStub)
  160.         If @error Then Return SetError(1, 0, False)
  161.         If $aTmp[0] = $hStub Then Return SetError(1, 0, False)
  162.         If $aTmp[0] = 0 Then
  163.             For $i = 0 To 255
  164.                 If $ga_DllCallBack_hGlobals[$i] = $hStub Then
  165.                     $ga_DllCallBack_hGlobals[$i] = ""
  166.                     $ga_DllCallBack_sParameters[$i] = ""
  167.                     $ga_DllCallBack_nParameters[$i] = ""
  168.                     $ga_DllCallBack_sFunctions[$i] = ""
  169.                     ExitLoop
  170.                 EndIf
  171.             Next
  172.             $hStub = 0
  173.             $gi_DllCallBack_StubCount -= 1
  174.             If $gi_DllCallBack_StubCount < 1 Then
  175.                 $gi_DllCallBack_StubCount = 0
  176.                 $aTmp = DllCall("kernel32.dll", "int", "FreeLibrary", "ptr", $gh_DllCallBack_hUser32)
  177.                 If @error Then Return SetError(2, 0, False)
  178.                 If $aTmp[0] = 0 Then Return SetError(2, 0, False)
  179.                 $gh_DllCallBack_hUser32 = 0
  180.             EndIf
  181.             Return True
  182.         EndIf
  183.         Return False
  184.     EndIf
  185.     Return True
  186. EndFunc   ;==>_DllCallBack_Free
  187.  
  188. Func __DllCallBack_MsgHandler($hWnd_Callback, $uiMsg, $wParam, $lParam)
  189.     Local $vParameters, $i
  190.     $vParameters = DllStructCreate($ga_DllCallBack_sParameters[$wParam], $lParam)
  191.     If $ga_DllCallBack_nParameters[$wParam] > 0 Then
  192.         Local $aCallArgs[$ga_DllCallBack_nParameters[$wParam] + 1]
  193.         $aCallArgs[0] = "CallArgArray"
  194.         For $i = 1 To $ga_DllCallBack_nParameters[$wParam]
  195.             $aCallArgs[$i] = DllStructGetData($vParameters, $i)
  196.         Next
  197.         Return Call($ga_DllCallBack_sFunctions[$wParam], $aCallArgs)
  198.     EndIf
  199.     Return Call($ga_DllCallBack_sFunctions[$wParam])
  200. EndFunc   ;==>__DllCallBack_MsgHandler